package com.kb.service.impl.components;

import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.json.JSONUtil;
import com.kb.common.MeException;
import com.kb.dto.components.LoginRequest;
import com.kb.dto.components.RemoteApiComponentsDTO;
import com.kb.service.ComponentService;
import com.kb.vo.components.ComponentPriceVO;
import com.kb.vo.components.ComponentStockVO;
import com.kb.vo.components.LoginResponseVO;
import com.kb.vo.components.RemoteCommonResultVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.compress.utils.Lists;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

@Service
@Slf4j
public class ComponentServiceImpl implements ComponentService {

    @Resource(name = "componentExecutor")
    private ThreadPoolExecutor componentExecutor;

    private static final Map<String, String> SUPPLIER_MAP = new HashMap<>();
    private static final Map<String, String> SUPPLIER_NAME_MAP = new HashMap<>();

    static {
        SUPPLIER_MAP.put("1", "VEND0004");
        SUPPLIER_MAP.put("2", "VEND0005");
        SUPPLIER_MAP.put("3", "VEND0006");
        SUPPLIER_MAP.put("4", "VEND0007");
        SUPPLIER_MAP.put("5", "VEND0008");
    }

    static {
        SUPPLIER_NAME_MAP.put("VEND0004", "昴氏电子元器件");
        SUPPLIER_NAME_MAP.put("VEND0005", "得捷电子");
        SUPPLIER_NAME_MAP.put("VEND0006", "易洛盟");
        SUPPLIER_NAME_MAP.put("VEND0007", "云汉");
        SUPPLIER_NAME_MAP.put("VEND0008", "圣禾堂");
    }

    /**
     * 远程调用接口查询询价接口
     *
     * @param dtoList
     * @return
     */
    @Override
    public List<ComponentPriceVO> queryRemoteApi(List<RemoteApiComponentsDTO> dtoList) {
        if (CollectionUtils.isEmpty(dtoList)) {
            return Lists.newArrayList();
        }
        dtoList.forEach(x -> {
            if (StringUtils.isEmpty(x.getSupplier())) {
                x.setSupplier(String.join(",", SUPPLIER_MAP.values()));
            } else {
                String[] split = StringUtils.split(x.getSupplier(), ",");
                x.setSupplier(Arrays.stream(split).map(SUPPLIER_MAP::get).collect(Collectors.joining(",")));
            }

        });
        LoginResponseVO loginResponseVO = doLogin(dtoList.get(0).getUsername(), dtoList.get(0).getPassword());
        if (Objects.isNull(loginResponseVO) || !Objects.equals(loginResponseVO.getCode(), 0) || Objects.isNull(loginResponseVO.getData())) {
            log.error("调用远程登录接口报错{}", loginResponseVO.toString());
            throw new MeException("调用远程登录接口报错【" + loginResponseVO.getMsg() + "】");
        }
        LoginResponseVO.LoginData data = loginResponseVO.getData();
        String accessToken = data.getAccessToken();
        if (dtoList.size() == 1) {
            List<ComponentPriceVO> componentPriceVOS = doRemoteApiQueryComponentData(accessToken, dtoList.get(0));
            componentPriceVOS.forEach(x -> x.getStockInfo().setSupplierName(SUPPLIER_NAME_MAP.get(x.getStockInfo().getSupplierCode())));
            return componentPriceVOS;
        } else {
            // 1. 生成索引与DTO的映射（保留原始顺序信息）
            List<ComponentPriceVO> dataRemoteAPI = IntStream.range(0, dtoList.size())
                    // 把索引和对应的DTO打包成数组（[索引, dto]）
                    .mapToObj(i -> new Object[]{i, dtoList.get(i)})
                    // 2. 异步执行时携带索引，结果也包含索引
                    .map(indexAndDto -> CompletableFuture.supplyAsync(() -> {
                        int index = (int) indexAndDto[0];
                        RemoteApiComponentsDTO rowData = (RemoteApiComponentsDTO) indexAndDto[1];
                        // 执行查询，返回「索引+结果」的映射
                        List<ComponentPriceVO> result = doRemoteApiQueryComponentData(accessToken, rowData);
                        return new AbstractMap.SimpleEntry<>(index, result);
                    }, componentExecutor))
                    // 收集所有异步任务
                    .collect(Collectors.toList())
                    // 3. 等待所有任务完成，按索引排序后提取结果
                    .stream()
                    .map(CompletableFuture::join) // 获取每个任务的「索引+结果」
                    .sorted(Map.Entry.comparingByKey()) // 按原始索引排序
                    .flatMap(entry -> entry.getValue().stream()) // 提取排序后的结果
                    .collect(Collectors.toList());
            dataRemoteAPI.forEach(x -> x.getStockInfo().setSupplierName(SUPPLIER_NAME_MAP.get(x.getStockInfo().getSupplierCode())));
            return dataRemoteAPI;
        }

    }

    public List<ComponentPriceVO> groupBySupplierCode(List<ComponentPriceVO> data) {
        // 按supplierCode分组，处理可能的null值
        Map<String, List<ComponentPriceVO>> groupedMap = data.stream().filter(x -> Objects.nonNull(x.getStockInfo()))
                .collect(Collectors.groupingBy(price ->
                        // 安全获取supplierCode，避免空指针
                        Optional.ofNullable(price.getStockInfo())
                                .map(ComponentStockVO::getSupplierCode)
                                .orElse(null)
                ));

        // 为每个分组创建父对象并设置children
        List<ComponentPriceVO> result = new ArrayList<>();
        for (Map.Entry<String, List<ComponentPriceVO>> entry : groupedMap.entrySet()) {
            String supplierCode = entry.getKey();
            List<ComponentPriceVO> children = entry.getValue();

            // 创建父对象
            ComponentPriceVO parent = new ComponentPriceVO();
            // 设置父对象的supplierCode（通过stockInfo关联）
            ComponentStockVO parentStock = new ComponentStockVO();
            parentStock.setSupplierCode(supplierCode);
            parentStock.setSupplierName(SUPPLIER_NAME_MAP.get(supplierCode));
            parent.setStockInfo(parentStock);
            // 设置子对象列表
            parent.setChildren(children);

            result.add(parent);
        }

        return result;
    }

    /**
     * 执行登录操作
     *
     * @param username 用户名
     * @param password 密码
     * @return 登录响应对象
     */
    @Override
    public LoginResponseVO doLogin(String username, String password) {
        // 创建登录请求参数对象
        LoginRequest request = new LoginRequest(username, password);

        HttpResponse response = HttpRequest.post("http://192.168.10.24:48080/admin-api/system/auth/login")
                .contentType("application/json")
                .body(JSONUtil.toJsonStr(request))
                .timeout(30000)  // 超时时间30秒
                .execute();
        return JSONUtil.toBean(response.body(), LoginResponseVO.class);
    }

    /**
     * 执行远程调用api操作
     *
     * @param accessToken 用户名
     * @param dto         密码
     * @return 登录响应对象
     */
    public List<ComponentPriceVO> doRemoteApiQueryComponentData(String accessToken, RemoteApiComponentsDTO dto) {
        HttpResponse response = HttpRequest.post("http://192.168.10.24:48080/admin-api/quote/forRemote/queryList")
                .header("Content-Type", "application/json")
                .header("Authorization", "Bearer " + accessToken)
                .body(JSONUtil.toJsonStr(dto))
                .execute();

        RemoteCommonResultVO bean = JSONUtil.toBean(response.body(), RemoteCommonResultVO.class);
        if (Objects.isNull(bean) || !Objects.equals(bean.getCode(), 0) || Objects.isNull(bean.getData())) {
            log.error("调用远程查询询价接口报错{}", bean.toString());
            throw new MeException("调用远程查询询价接口报错");
        }
        return bean.getData();
    }
}
